/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package functions;

import GUI.other.LoadingForm;
import Update.DBUpdate;
import java.awt.Color;
import java.awt.Component;
import java.awt.Toolkit;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import model.Doctor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import model.Company;
import model.Database;
import Interfaces.Loadable;
import java.awt.Dimension;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import javax.swing.JFrame;


/**
 *
 * @author JArik
 */
public class Dogy {
    public static String
                 REPORT_DIR=".";
    private Doctor doctor;
    private static JDialog dial;

    public static double DRUG_TAX=9.0,
                         VAT_TAX=20.0;

    public static int DB_VERSION = 3; // compatible with db version
    public static double VERSION = 5.1;   // current version
    public static String V_PREFIX = "TEST";
    public static boolean NEW_VERSION_READY = false;

    public static String UPDATE_URL = "http://www.polpiva.pri.ee/dogy";
    public static String WEB_CONTROL_URL = "http://www.polpiva.pri.ee/dogy";
    
    public static String DB_ADDRESS= "localhost:3306";
    public static String DB_USER= "root";
    public static String DB_PASS= "q1";
    public static String DB_NAME= "Dogy";

    public static String [] CURRENCY = new String[]{"EEK","EUR"};
    private static Properties properties = new Properties();

    //
    private static SwingWorker worker;
    private static LoadingForm loading;
    private static Integer taskNum;
    private static HashMap<String,Integer> tasks;

    public Dogy(String db, String username, String pass) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException
    {
          //update();
        Database.connect(db, username, pass);
        dbUpdate();
          
    }
    

    public Dogy() throws SQLException
    {
        retreiveSettings();
        dbUpdate();
        //update();
    }

    public void connect(String db, String username, String pass) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException {
        Database.connect(db, username, pass);
    }
    
    // get Active( logined doctor profile )
    public Doctor getDoctor()
    {
        return doctor;
    }

    public static void saveSettings()
    {
            try
            {
              properties.setProperty("drug_tax", Dogy.DRUG_TAX+"");
              properties.setProperty("vat_tax", Dogy.VAT_TAX+"");
              properties.setProperty("reportDir", Dogy.REPORT_DIR);
              properties.setProperty("version", Dogy.DB_VERSION+"");
              properties.setProperty("dbAddress", Dogy.DB_ADDRESS+"");
              properties.store(new FileOutputStream("settings.ini"), "");
              Dogy.incrLoadingProgress(100,"settingsCheck","Завершение...");
            } catch(Exception ec)
            {
                LogError.reportSilentError(ec);
                System.out.println("Can't create: "+ec);
            }
    }
    public static void retreiveSettings()
    {
        try
        {
          Dogy.incrLoadingProgress(30,"settingsCheck","Чтение...");
          properties.load(new FileInputStream("settings.ini"));
          DRUG_TAX = Double.parseDouble(properties.getProperty("drug_tax"));
          VAT_TAX = Double.parseDouble(properties.getProperty("vat_tax"));

          if(properties.getProperty("version") != null)
            DB_VERSION = Integer.parseInt(properties.getProperty("version"));
          if(properties.getProperty("reportDir") != null)
            REPORT_DIR = properties.getProperty("reportDir");
          if(properties.getProperty("dbAddress") != null)
            DB_ADDRESS = properties.getProperty("dbAddress");

          Dogy.incrLoadingProgress(100,"settingsCheck","Завершение...");
        }catch(Exception e)
        {
            try {
                Dogy.incrLoadingProgress(60, "settingsCheck", "Сохранение...");
            } catch (Exception ex) {
            }
            Dogy.saveSettings();
        }
    }

    public static void checkOnlineUpdate(String domenPath)
    {
        try {
        String dataToSend = "prefix="+Dogy.V_PREFIX+"&version="+Dogy.VERSION;
        URL update = new URL(domenPath+"/checkRelease.php");
        URLConnection updateConnection = update.openConnection();
        Dogy.incrLoadingProgress(10,"updateCheck","Подключение...");
        updateConnection.setDoOutput(true);
        OutputStreamWriter wr = new OutputStreamWriter(updateConnection.getOutputStream());
        wr.write(dataToSend);
        wr.flush();
        wr.close();
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                updateConnection.getInputStream(),"UTF-8"));
        String inputLine;
        
        double downloaded = 0;
        double perc =0;
        while ((inputLine = in.readLine()) != null)
        {
                if(!inputLine.isEmpty() && !inputLine.equals("error"))
                {
                    Dogy.NEW_VERSION_READY = true;
                    URL download = new URL(domenPath+"/"+inputLine);
                    URLConnection downConnection = download.openConnection();
                    downConnection.connect();
                    
                    FileOutputStream fos = new FileOutputStream("update.jar");
                    BufferedOutputStream bout = new BufferedOutputStream(fos,1024);
                    BufferedInputStream bin = new BufferedInputStream(downConnection.getInputStream());

                    byte data[] = new byte[1024];
                    int count = 0;
                    while((count = bin.read(data,0,1023))>= 0)
                    {
                        bout.write(data,0,count);
                        downloaded+=count;
                        perc = downloaded/(double)downConnection.getContentLength();
                        Dogy.incrLoadingProgress((int) (10 + (80 * perc)),"updateCheck","Скачивание... "+(int)(perc*100));
                    }
                    Dogy.incrLoadingProgress(95,"updateCheck","Сохранение...");
                    bin.close();
                    bout.close();
                    fos.close();
                    Dogy.NEW_VERSION_READY = true;
                }
        }
        
        Dogy.incrLoadingProgress(100,"updateCheck","Завершение...");
        in.close();
        } catch(Exception e)
        {
            LogError.reportSilentError(e);
            e.printStackTrace();
        }
    }

    public static void updateVersionTo(int newVersion)
    {
        
        properties.setProperty("version", newVersion+"");
        try
        {
          properties.store(new FileOutputStream("settings.ini"), "");
          Dogy.DB_VERSION = newVersion;
        }catch(Exception ec)
        { System.out.println("Can't create: "+ec);   }
    }

    public static void dbUpdate() throws SQLException
    {
        if(DB_VERSION < DBUpdate.DB_VERSION)
            Dogy.updateVersionTo(DBUpdate.doUpdate(DB_VERSION));
        
    }
    public static Company getCompanyFullInfo(int compId) throws SQLException
    {
        Database db = new Database();
        ResultSet set = db.getDBInfo("id, name, address, regNr, tel",
                "company", " id ="+compId);
        Company res = null;
        if (set.next() && set.getInt(1) != 0) {
            res = new Company(set.getInt(1), set.getString(2), set.getInt(4));
            res.setTel(set.getString(5));
            res.setAddress(set.getString(3));
        } else {
            throw new SQLException("Access denied");
        }
        db.closeStatement();
        return res;
    }

    
    public void createProfile(String login, String pass) throws SQLException {
        Database db = new Database();
        ResultSet set = db.getDBInfo("id, name, surname, login, status",
                "profiles", "login = '" + login + "' AND pass = '" + pass + "' AND deleted=0");
        if (set.next() && set.getInt(1) != 0) {
            doctor = new Doctor(set.getInt(1), set.getString(2), set.getString(3));
            doctor.setLoginName(set.getString(4));
            doctor.setStatus(set.getInt(5));
            db.closeStatement();
        } else {
            throw new SQLException("Access denied");
        }
    }

    public Doctor getProfile() {
        return doctor;
    }

    public static void placeToCenter(Component comp) {
        comp.setLocation(
                (Toolkit.getDefaultToolkit().getScreenSize().width - comp.getWidth()) / 2,
                ((Toolkit.getDefaultToolkit().getScreenSize().height - comp.getHeight()-15) / 2)) ;
    }
    public static void reSizeAndCenter(JFrame frame)
    {
        int sWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
        int sHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
        frame.setBounds((sWidth - frame.getWidth())/2,
                        (sHeight - frame.getHeight())/2,
                        (int)(sWidth*0.9), (int)(sHeight*0.95));
    }
    public static void reSize(JFrame frame)
    {
        int sWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
        int sHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
        //comp.setSize((int)(sWidth*0.7), (int)(sHeight*0.7));
        Dimension dim = new Dimension((int)(sWidth*0.9), (int)(sHeight*0.95));
        //frame.setPreferredSize(dim);
        frame.setMaximumSize(new Dimension(sWidth, sHeight));
        if(frame.getPreferredSize().getHeight() > dim.getHeight() ||
                frame.getPreferredSize().getWidth() > dim.getWidth())
            frame.setPreferredSize(dim);
        if(sWidth <= 800 || sHeight <=600)
          frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        
    }

    public static void cleanField(final JTextField field) {
        Runnable t = new Runnable() {

            public void run() {
                field.setText("");
            }
        };
        java.awt.EventQueue.invokeLater(t);
    }
    
    public static void closeLoading()
    {
        dial.dispose();
    }

    public static void focusGained(JTextField obj, String text) {
        if (obj.getText().equals("") ||
                obj.getText().equals(text)) {
            obj.setText("");
        }
        obj.setForeground(Color.black);
    }

    public static void focusLost(JTextField obj, String text) {
        if (obj.getText().equals("")) {
            obj.setText(text);
            obj.setForeground(Color.gray);
        }
    }

    public static String convertToLatin(String text) {
        if(text == null) return "";
        String res = "";
        String textTemp = text;
        text = text.toLowerCase();
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            switch (c) {
                case 'а':
                    res += "a";
                    break;
                case 'б':
                    res += "b";
                    break;
                case 'в':
                    res += "v";
                    break;
                case 'г':
                    res += "g";
                    break;
                case 'д':
                    res += "d";
                    break;
                case 'е':
                    res += "e";
                    break;
                case 'ё':
                    res += "e";
                    break;
                case 'ж':
                    res += "zh";
                    break;
                case 'з':
                    res += "z";
                    break;
                case 'и':
                    res += "i";
                    break;
                case 'й':
                    res += "i";
                    break;
                case 'к':
                    res += "k";
                    break;
                case 'л':
                    res += "l";
                    break;
                case 'м':
                    res += "m";
                    break;
                case 'н':
                    res += "n";
                    break;
                case 'о':
                    res += "o";
                    break;
                case 'п':
                    res += "p";
                    break;
                case 'р':
                    res += "r";
                    break;
                case 'с':
                    res += "s";
                    break;
                case 'т':
                    res += "t";
                    break;
                case 'у':
                    res += "u";
                    break;
                case 'ф':
                    res += "f";
                    break;
                case 'х':
                    res += "h";
                    break;
                case 'ч':
                    res += "ch";
                    break;
                case 'щ':
                    res += "sh";
                    break;
                case 'ш':
                    res += "sh";
                    break;
                case 'ц':
                    res += "ts";
                    break;
                case 'э':
                    res += "e";
                    break;
                case 'ы':
                    res += "i";
                    break;
                case 'я':
                    res += "ja";
                    break;
                case 'ю':
                    res += "ju";
                    break;
                case 'ь':
                    res += "'";
                    break;
                case 'ъ':
                    res += "";
                    break; 
                default:
                    res +=c +"";
                    break;
            }
        }
        char [] array = res.toCharArray();
        array[0] =  String.valueOf(array[0]).toUpperCase().charAt(0);
        /*for(int i=0;i< textTemp.length(); i++)
            if(textTemp.substring(i, i+1).toUpperCase().equals(
               textTemp.substring(i, i+1)))
            {
                
            }*/
        return new String(array);
    }
    public static double roundTwoDecimals(double d) {
        double res = d*100;
        res += 0.5;
        res = Math.floor(res);
        res /= 100;
        //DecimalFormat twoDForm = new DecimalFormat("#.##");
		return res;//Double.valueOf(twoDForm.format(d));
    }
    public static double roundPrice(double d) {
        double res = d*10;
        res = Math.ceil(res);
        res /= 10;
		return res;//Double.valueOf(twoDForm.format(d));
    }
    public static void listScroll(JList list, java.awt.event.KeyEvent evt)
    {
            if(evt.getKeyCode() == evt.VK_DOWN)
            {
                list.setSelectedIndex(list.getSelectedIndex()+1);
                int vR = (list.getLastVisibleIndex() - list.getFirstVisibleIndex())/2;
                list.ensureIndexIsVisible(list.getSelectedIndex()+ vR);
            }
            if(evt.getKeyCode() == evt.VK_UP)
            {
               if(list.getSelectedIndex() >0)
               {
                list.setSelectedIndex(list.getSelectedIndex()-1);
                int vR = (list.getLastVisibleIndex() - list.getFirstVisibleIndex())/2;
                int vis = list.getSelectedIndex()- vR;
                if (vis < 0) vis = 0;
                list.ensureIndexIsVisible(vis);
               }
            }
            int dist = list.getLastVisibleIndex() - list.getFirstVisibleIndex();
            if(evt.getKeyCode() == evt.VK_PAGE_DOWN)
            {
                list.setSelectedIndex(list.getFirstVisibleIndex()+dist);
                int vR = (list.getLastVisibleIndex() - list.getFirstVisibleIndex())/2;
                list.ensureIndexIsVisible(list.getSelectedIndex()+ vR);
            }
            if(evt.getKeyCode() == evt.VK_PAGE_UP)
            {
               if(list.getSelectedIndex() <= dist)
               {
                 list.setSelectedIndex(0);
                 list.ensureIndexIsVisible(0);
               }
               else
               {
                
                list.setSelectedIndex(list.getFirstVisibleIndex());
                int vR = (list.getLastVisibleIndex() - list.getFirstVisibleIndex())/2;
                int vis = list.getFirstVisibleIndex() - vR;
                list.ensureIndexIsVisible(vis);

               }
               
            }
    }

    public static void initLoading(Integer ts, String lText, final Loadable obj)
    {
        tasks = new HashMap<String,Integer>();
        taskNum = ts;
        loading = new LoadingForm(lText, obj);
        final JDialog dialog = new JDialog();
        dialog.setAlwaysOnTop(true);
        worker = new SwingWorker()
        {

            @Override
            protected Object doInBackground() throws Exception {
                loading.paintImmediately(loading.getBounds());
                return obj.load();
            }
            
            @Override
            protected void done()
            {
                obj.done(null);
                taskNum = 0;
                dialog.dispose();
            }

        };
        dialog.add(loading);
        dialog.pack();
        dialog.setVisible(true);
        Dogy.placeToCenter(dialog);
        worker.execute();
    }

    public static boolean stopLoading()
    {
        if(worker != null)
        {
          if(worker.cancel(true))
            loading.getLoadable().cancel();
          return worker.isCancelled();
        }
        return false;
    }

    public static void incrLoadingProgress(int pr, String taskName,
                                                   String taskDescr)
                                                   throws Exception
    {
        try
        {
            if(tasks == null || loading == null) return;
            tasks.put(taskName, pr);
            loading.setDescrLabel(taskDescr);
            Object [] percs = tasks.values().toArray();
            int perc = 0;
            if(taskNum == 0 )
                taskNum = percs.length;
            
            for(int i=0; i<percs.length; i++)
            {
              perc += (Integer)percs[i]/taskNum;
            }
            loading.setProgress(perc);
            loading.paintImmediately(loading.getBounds());
        } catch(Exception e)
        {
            e.printStackTrace();
        }
        if(worker.isCancelled())
        {
            throw new Exception("Aborted");
        }
    }




    public static ArrayList<String> getStreetLike(String name) throws SQLException
    {
        Database db = new Database();
        ResultSet set = db.getDBInfo("SELECT DISTINCT address FROM users WHERE address LIKE '%"+name+"%' ORDER BY" +
                "                     address != '"+name+"' ");
        ArrayList<String> adrs = new ArrayList<String>();
        String temp;
        while(set.next())
        {
            temp = set.getString("address").split(" ")[0];
            if(!adrs.contains(temp))
            adrs.add(set.getString("address").split(" ")[0]);
        }
        return adrs;
    }
}